/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ajustecurvas.controller;

import ajustecurvas.Ponto;
import ajustecurvas.utils.CriaMatriz;
import ajustecurvas.utils.Gauss;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author João Gabriel QA
 */
public class ParabolaAjusteController extends AjusteController{

    private double pearson;
    private double[] variaveis;
    /*
    public void parabola() {
        double[] eixoX = {1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0};
        double[] eixoY = {0.5250, 0.7448, 1.2807, 1.9934, 2.5326, 3.5386, 5.4400, 6.6258, 9.7768, 11.5076, 14.9484};
        double[] vetorResposta, variaveis, resultado;
        double[][] entradaMatriz, matrizAmpliada, matrizResolvida;

        CriaMatriz matriz = new CriaMatriz();
        System.out.println("Matriz da parábola: ");
        entradaMatriz = matriz.criaMatriz(eixoX);
        printMatriz(entradaMatriz);
        System.out.println(" ");
        System.out.println("Vetor de resposta: ");
        vetorResposta = matriz.criaVetorResposta(eixoX, eixoY);
        printVetor(vetorResposta);
        System.out.println(" ");
        matrizAmpliada = criaMatrizAmpliada(entradaMatriz, vetorResposta);
        System.out.println("Matriz ampliada do sistema: ");
        printMatriz(matrizAmpliada);
        Gauss g = new Gauss();
        matrizResolvida = g.gauss(vetorResposta.length, matrizAmpliada, vetorResposta);
        System.out.println("");
        System.out.println("Valores das variaveis: ");
        System.out.println("");
        variaveis = g.pegaValorVariavel(matrizResolvida);

        System.out.println("");
        System.out.println("Valores Y: ");
        printVetor(eixoY);
        System.out.println("");
        System.out.println("Valores calculados: ");
        resultado = geraVetorResultado(variaveis, eixoX);
        printVetor(resultado);
        pearson(eixoY, resultado);
    }
    *
    */

    public static void printMatriz(double[][] matriz){
        for(int j = 0; j < matriz.length; j++){
            for(int i = 0; i < matriz[0].length; i++){
                System.out.print(matriz[j][i]+" ");
            }
            System.out.println(" ");
        }
    }

    public static void printVetor(double[] vetor){
        for(int i = 0; i < vetor.length; i++){
            System.out.print(vetor[i] + " ");
        }
    }

    private static double[][] criaMatrizAmpliada(double[][] matriz, double[] vetor){
        int i = 0, j = 0, k = 0;
        double[][] matrizAmpliada = new double[3][4];

        while(j < 3){
            while(i < 4){
                if(i < 3){
                    matrizAmpliada[j][i] = matriz[j][i];
                    //i++;
                }else{
                    matrizAmpliada[j][i] = vetor[k];
                    break;
                }
                i++;
            }
            k++;
            j++;
            i = 0;
            //System.out.println("k: " + k + "j: " + j);
        }
        return matrizAmpliada;
    }

    public static double[] geraVetorResultado(double[] variaveis, double[] eixoX){
        double[] resultadoFinal = new double[eixoX.length];

        for(int i = 0; i < eixoX.length; i++){
            resultadoFinal[i] = (variaveis[0]*Math.pow(eixoX[i], 2)) + (variaveis[1]*eixoX[i]) + variaveis[2];
        }
        return resultadoFinal;
    }

    public double pearson(double[] eixoY, double[] resposta){

        double numerador, denominador1, denominador2, temp = 0, temp2 = 0, temp3 = 0, div, ps;

        for(int i = 0; i < eixoY.length; i++){
            temp += Math.pow(eixoY[i]-resposta[i], 2);
            temp2 += Math.pow(eixoY[i], 2);
            temp3 += eixoY[i];
        }

        numerador = eixoY.length*temp;
        denominador1 = eixoY.length*temp2;
        denominador2 = Math.pow(temp3, 2);
        div = numerador/(denominador1-denominador2);
        ps = 1-div;
        //System.out.println("");
        //System.out.println("Coeficiente de correlação de Pearson: " + ps);
        return ps;
    }

    @Override
    public List<Ponto> calcular(List<Ponto> medidas) {
        double[] eixoX = new double[medidas.size()];// = {1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0};
        double[] eixoY = new double[medidas.size()];// = {0.5250, 0.7448, 1.2807, 1.9934, 2.5326, 3.5386, 5.4400, 6.6258, 9.7768, 11.5076, 14.9484};
        double[] vetorResposta, resultado;
        double[][] entradaMatriz, matrizAmpliada, matrizResolvida;
        ArrayList<Ponto> p = new ArrayList();

        for(int i = 0; i < eixoX.length; i++){
            eixoX[i] = medidas.get(i).getX();
            eixoY[i] = medidas.get(i).getY();
        }

        CriaMatriz matriz = new CriaMatriz();
        //System.out.println("Matriz da parábola: ");
        entradaMatriz = matriz.criaMatriz(eixoX);
        //printMatriz(entradaMatriz);
        //System.out.println(" ");
        //System.out.println("Vetor de resposta: ");
        vetorResposta = matriz.criaVetorResposta(eixoX, eixoY);
        //printVetor(vetorResposta);
        //System.out.println(" ");
        matrizAmpliada = criaMatrizAmpliada(entradaMatriz, vetorResposta);
        //System.out.println("Matriz ampliada do sistema: ");
        //printMatriz(matrizAmpliada);
        Gauss g = new Gauss();
        matrizResolvida = g.gauss(vetorResposta.length, matrizAmpliada, vetorResposta);
        //System.out.println("");
        //System.out.println("Valores das variaveis: ");
        //System.out.println("");
        variaveis = g.pegaValorVariavel(matrizResolvida);

        //System.out.println("");
        //System.out.println("Valores Y: ");
        //printVetor(eixoY);
        //System.out.println("");
        //System.out.println("Valores calculados: ");
        resultado = geraVetorResultado(variaveis, eixoX);
        //printVetor(resultado);
        pearson = pearson(eixoY, resultado);

        for(int j = 0; j < eixoX.length; j++){
            Ponto pr = new Ponto(eixoX[j], resultado[j]);
            p.add(pr);
        }
        return p;
    }


    @Override
    public String getEquacao() {
        DecimalFormat df = new DecimalFormat("0.00");
        String a = df.format(variaveis[0]);
        String b = df.format(variaveis[1]);
        String c = df.format(variaveis[2]);
        String eq = a + "* X^2 +(" + b + "* X) +" +"("+ c +")";

        return eq;
    }

    @Override
    public double getQualidade() {
        return pearson;
    }

}
